#include "task_shell.h"
#include "lib_string.h"
#include "board.h"
#include "shell.h"

#define SHELL_ECHO 1
#ifdef SHELL_ECHO
#define shell_printf raw_printf
#else
#define shell_printf
#endif

Shell active_shell;
IDLE_QUEUE_MSG queue_shell[5];

static RAW_U16 shell_initial(Shell *me, STATE_EVENT *e);
static RAW_U16 shell_process(Shell *me, STATE_EVENT *e);

static void shell_ctor(Shell *me)
{
	FSM_CONSTRUCTOR(&me->evt.super, (stm_state_handler)&shell_initial);
	me->rx_cnt = 0;
	raw_memset(me->buf, 0, SHELL_RX_SIZE);
}

static RAW_U16 shell_initial(Shell *me, STATE_EVENT *e)
{
	me->rx_cnt = 0;
	raw_memset(me->buf, 0, SHELL_RX_SIZE);
	shell_printf("\r\nDEZO>>\r\n");
	return STM_TRAN(&shell_process);
}

static RAW_U16 shell_process(Shell *me, STATE_EVENT *e)
{
	ShellRet ret1 = RET_NULL, ret2 = RET_NULL;
	RAW_U16 status = STM_RET_IGNORED;
	ShellManage *Shellptr = YLN_NULL; 
	
	switch(e->sig)
	{
		case STM_ENTRY_SIG:
				status = STM_RET_HANDLED;
		break;
		case SHELL_PROCESS_SIG:
			Shellptr = shell_manage_get(); 
			ret1 = Shellptr->prefix_parase((char*)(me->buf));
			if(ret1 == RET_PREFIX_OK)
			{
					ret2 = Shellptr->params_parase();
					if(ret2 == RET_PARAMS_OK)
					{
							//shell_printf("Command OK!\r\n");
					}
					else
					{
//							shell_printf("Command Param Error!\r\n");
					}
			}
			else if(ret1 == RET_PARAMS_OK)
			{
					//shell_printf("Command OK!\r\n");
			}
			else
			{
//					shell_printf("Command Error!,please input again. input \'help\' for command details.\r\n");
			}
			me->rx_cnt = 0;
			raw_memset(me->buf, 0, SHELL_RX_SIZE);
			shell_printf("\r\nDEZO>>\r\n");
		default: break;
	}
	return status;
}

static void shell_uart_callback(unsigned char ch)
{
	if(ch == '\n')   //Enter
	{
		if(active_shell.rx_cnt > 0) active_shell.rx_cnt--;
		active_shell.buf[active_shell.rx_cnt] = '\0';
		event_end_post(&active_shell.evt, SHELL_PROCESS_SIG, 0);
	}
	else if(ch == '\b')    //backspace
	{
		active_shell.buf[active_shell.rx_cnt] = '\0';
		if(active_shell.rx_cnt > 0) active_shell.rx_cnt--;
	}
	else
	{
		if(active_shell.rx_cnt < SHELL_RX_SIZE)
		{
			active_shell.buf[active_shell.rx_cnt] = ch;
			active_shell.rx_cnt++;
		}
		else
		{
			event_end_post(&active_shell.evt, SHELL_PROCESS_SIG, 0);
		}
	}
}

void shell_task_init(void)
{
    com_shell_console_register_callback(shell_uart_callback);
    shell_ctor(&active_shell);
    fsm_init(&active_shell.evt.super, 0);
}
